package com.kinsin.kinsinutil

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.File

@RunWith(AndroidJUnit4::class)
class FileUtilInstrumentedTest {
    private lateinit var fileUtilWithOutPermission: FileUtilWithOutPermission
    private val testFileName = "test_file.txt"
    private val testBinaryFile = "test_data.bin"
    private val testDirName = "test_dir"
    private val testContent = "Hello, Android Unit Test!"
    private val testBytes = byteArrayOf(0x48, 0x65, 0x6C, 0x6C, 0x6F) // "Hello" in hex

    @Before
    fun setup() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        fileUtilWithOutPermission = FileUtilWithOutPermission.getInstance(context)
    }

    @After
    fun tearDown() {
        // Clean up all test files
        fileUtilWithOutPermission.deleteFile(testFileName)
        fileUtilWithOutPermission.deleteFile(testBinaryFile)
        fileUtilWithOutPermission.deleteDirectory(testDirName)
    }

    @Test
    fun testStringFileOperations() {
        // Save and read string
        assertTrue(fileUtilWithOutPermission.saveStringToFile(testFileName, testContent))
        assertEquals(testContent, fileUtilWithOutPermission.readStringFromFile(testFileName))
    }

    @Test
    fun testBinaryFileOperations() {
        // Save and read bytes
        assertTrue(fileUtilWithOutPermission.saveBytesToFile(testBinaryFile, testBytes))
        assertArrayEquals(testBytes, fileUtilWithOutPermission.readBytesFromFile(testBinaryFile))
    }

    @Test
    fun testFileDeletion() {
        fileUtilWithOutPermission.saveStringToFile(testFileName, testContent)
        assertTrue(fileUtilWithOutPermission.deleteFile(testFileName))
        assertNull(fileUtilWithOutPermission.readStringFromFile(testFileName))
    }

    @Test
    fun testFileRename() {
        val newFileName = "renamed_file.txt"
        fileUtilWithOutPermission.saveStringToFile(testFileName, testContent)
        
        assertTrue(fileUtilWithOutPermission.renameFile(testFileName, newFileName))
        assertEquals(testContent, fileUtilWithOutPermission.readStringFromFile(newFileName))
        assertNull(fileUtilWithOutPermission.readStringFromFile(testFileName))
        
        // Cleanup
        fileUtilWithOutPermission.deleteFile(newFileName)
    }

    @Test
    fun testDirectoryOperations() {
        // Create directory
        assertTrue(fileUtilWithOutPermission.createDirectory(testDirName))
        assertTrue(fileUtilWithOutPermission.directoryExists(testDirName))

        // Create nested directory
        val nestedDir = "$testDirName/sub_dir"
        assertTrue(fileUtilWithOutPermission.createDirectory(nestedDir))
        assertTrue(fileUtilWithOutPermission.directoryExists(nestedDir))

        // Delete directory
        assertTrue(fileUtilWithOutPermission.deleteDirectory(testDirName))
        assertFalse(fileUtilWithOutPermission.directoryExists(testDirName))
    }

    @Test
    fun testFilePath() {
        fileUtilWithOutPermission.saveStringToFile(testFileName, testContent)
        val expectedPath = File(fileUtilWithOutPermission.getFilePath("")).absolutePath + File.separator + testFileName
        assertEquals(expectedPath, fileUtilWithOutPermission.getFilePath(testFileName))
    }

    @Test
    fun testReadNonExistentFile() {
        assertNull(fileUtilWithOutPermission.readStringFromFile("non_existent.txt"))
        assertNull(fileUtilWithOutPermission.readBytesFromFile("non_existent.bin"))
    }

    @Test
    fun testSingletonInstance() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        val instance1 = FileUtilWithOutPermission.getInstance(context)
        val instance2 = FileUtilWithOutPermission.getInstance(context)
        assertSame(instance1, instance2)
    }

    @Test
    fun testFileInDirectory() {
        fileUtilWithOutPermission.createDirectory(testDirName)
        val nestedFile = "$testDirName/nested.txt"
        
        assertTrue(fileUtilWithOutPermission.saveStringToFile(nestedFile, testContent))
        assertEquals(testContent, fileUtilWithOutPermission.readStringFromFile(nestedFile))
        
        assertTrue(fileUtilWithOutPermission.deleteFile(nestedFile))
        assertTrue(fileUtilWithOutPermission.deleteDirectory(testDirName))
    }

    @Test
    fun testEmptyFileOperations() {
        // 测试空内容
        assertTrue(fileUtilWithOutPermission.saveStringToFile("empty.txt", ""))
        assertEquals("", fileUtilWithOutPermission.readStringFromFile("empty.txt"))

        // 测试空字节数组
        assertTrue(fileUtilWithOutPermission.saveBytesToFile("empty.bin", byteArrayOf()))
        assertArrayEquals(byteArrayOf(), fileUtilWithOutPermission.readBytesFromFile("empty.bin"))
    }

    @Test
    fun testSpecialCharacters() {
        val content = "特殊字符测试 ěščřžýáíé"
        assertTrue(fileUtilWithOutPermission.saveStringToFile("special.txt", content))
        assertEquals(content, fileUtilWithOutPermission.readStringFromFile("special.txt"))
    }
}